<?php
/**
 * Created by PhpStorm
 * author  :gogochen
 * date    :2019/12/13
 * time    :11:27
 */

namespace App;

use App\Manager\DataCenter;
use App\Manager\Logic;
use App\Manager\TaskManager;

require_once __DIR__ . "/../vendor/autoload.php";

class Server
{
    CONST HOST = "0.0.0.0";
    CONST PORT = 9502;
    const FRONT_PORT = 9503;
    CONST CONFIG = [
        'worker_num' => 4,
        'document_root' => '/var/www/html/swooleGame/front/',
        'enable_static_handler' => true,
        'task_worker_num' => 4,
        'dispatch_mode' => 5
    ];

    private $ws;

    const CLIENT_CODE_MATCH_PLAYER = 600;

    const CLIENT_CODE_START_ROOM = 601;

    private $logic;

    public function __construct()
    {
        $this->logic = new Logic();
        $this->ws = new \Swoole\WebSocket\Server(self::HOST, self::PORT);
        $this->ws->set(self::CONFIG);
        $this->ws->listen(self::HOST, self::FRONT_PORT, SWOOLE_SOCK_TCP);
        $this->ws->on("start", [$this, 'onStart']);
        $this->ws->on("workerStart", [$this, 'onWorkerStart']);
        $this->ws->on("open", [$this, 'onOpen']);
        $this->ws->on("message", [$this, 'onMessage']);
        $this->ws->on("close", [$this, 'onClose']);
        $this->ws->on("task", [$this, 'onTask']);
        $this->ws->on("finish", [$this, "onFinish"]);
        $this->ws->start();
    }


    /**
     * description
     * @param $server
     */
    public function onStart($server)
    {
        swoole_set_process_name('hide-and-seek');
        echo sprintf(
            "master start (listening on %s:%d)" . PHP_EOL,
            self::HOST,
            self::PORT
        );
        //清除redis中的残留数据
        DataCenter::initDataCenter();
    }


    public function onWorkerStart($server, $workerId)
    {
        echo "server:onWorkerStart,worker_id:{$server->worker_id}" . PHP_EOL;

        DataCenter::$server = $server;
    }

    public function onOpen($server, $request)
    {
        DataCenter::log(sprintf('client open fd：%d', $request->fd));
        //将player_id和fd保存到DataCenter
        $playerId = $request->get['player_id'];
        DataCenter::setPlayerInfo($playerId, $request->fd);
    }

    public function onMessage($server, $request)
    {
        DataCenter::log(sprintf('client open fd：%d，message：%s', $request->fd, $request->data));
        $server->push($request->fd, 'test success');

        //根据fd找到playerId
        $data = json_decode($request->data, true);
        $playerId = DataCenter::getPlayerId($request->fd);

        switch ($data['code']) {
            case self::CLIENT_CODE_MATCH_PLAYER;
                $this->logic->matchPlayer($playerId);
                break;
            case self::CLIENT_CODE_START_ROOM;
                $this->logic->startRoom($data['room_id'], $playerId);
                break;
        }
    }

    public function onClose($server, $fd)
    {
        DataCenter::log(sprintf('client close fd: %d', $fd));
        //根据fd清除玩家信息
        DataCenter::delPlayerInfo($fd);
    }

    public function onTask($server, $taskId, $srcWorkerId, $data)
    {
        DataCenter::log("onTask", $data);
        $result = [];
        switch ($data['code']) {
            case TaskManager::TASK_CODE_FIND_PLAYER:
                $ret = TaskManager::findPlayer();
                if (!empty($ret)) {
                    $result['data'] = $ret;
                }
                break;
        }
        if (!empty($result)) {
            $result['code'] = $data['code'];
            return $result;
        }
    }


    public function onFinish($server, $taskId, $data)
    {
        DataCenter::log("onFinish", $taskId, $data);
        switch ($data['code']) {
            case TaskManager::TASK_CODE_FIND_PLAYER:
                $this->logic->createRoom($data['red_player'], $data['blue_player']);
                break;
        }
    }


}

new Server();